package com.starsoft.verifycode.filter;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.List;

public class GrayFilter {
	
	private int[][] pixels;
	private int iw;
	private int ih;

	public GrayFilter(BufferedImage image) {
		iw = image.getWidth();
		ih = image.getHeight();
		pixels = new int[ih][iw];
		for(int i=0;i<ih;i++){
			for(int j=0;j<iw;j++){
				pixels[i][j] = toGray2(image.getRGB(j, i)) ;
			}
		}
	}
	
	private int toGray(int rgb){
		Color color = new Color(rgb);
		int gray = color.getRed()+color.getBlue()+color.getGreen();
		gray = gray/3;
		return gray;
	}
	
	private int toGray2(int rgb){
		Color color = new Color(rgb);
		int gray = (int) (0.3*color.getRed()+0.59*color.getGreen()+0.11*color.getBlue());
		return gray;
	}
	
	public GrayFilter binarization(int th){
		for(int i=0;i<ih;i++){
			for(int j=0;j<iw;j++){
				int value = pixels[i][j];
				if(value>th){
					pixels[i][j] = 255;
				} else {
					pixels[i][j] = 0;
				}
			}
		}	
		return this;
	}
	
	public GrayFilter median(){
		int[][] temp = copy(pixels);
		for(int i=1;i<ih-1;i++){
			for(int j=1;j<iw-1;j++){
				pixels[i][j] = getMidValue(temp[i-1][j],temp[i][j-1], temp[i][j],temp[i+1][j],temp[i][j+1]);
			}
		}	
		return this;
	}
	
	public BufferedImage getImage(){
		BufferedImage image = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB);
		for(int i=0;i<ih;i++){
			for(int j=0;j<iw;j++){
				int value = pixels[i][j];
				Color color = new Color(value, value, value);
				image.setRGB(j, i, color.getRGB());
			}
		}	
		return image;
	}
	
	private int[][] copy(int[][] from){
		int[][] result = new int[from.length][from[0].length];
		for(int i=0;i<ih;i++){
			for(int j=0;j<iw;j++){
				result[i][j] = pixels[i][j];
			}
		}	
		return result;
	}
	
	private int getMidValue(int... values) {
		int len = values.length;
		int i, j, dct;
		for (i = len - 1; i > 0; i--) {
			for (j = 0; j < i; j++) {
				if (values[j] > values[j + 1]) {
					dct = values[j];
					values[j] = values[j + 1];
					values[j + 1] = dct;
				}
			}
		}
		int mid = values[len / 2];
		if (len % 2 == 0) {
			mid = (values[len / 2] + values[len / 2 + 1]) / 2;
		}
		return mid;
	}
}
